﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;

namespace BCCommon.Extensions
{
    public static class EnumExtension
    {
        public static Dictionary<string, string> EnumToDictionary<T>()
        {
            var enumType = typeof(T);
            if (!enumType.IsEnum)
            {
                throw new ArgumentException("传入的参数必须是枚举类型！");
            }
            Dictionary<string, string> dic = new Dictionary<string, string>();
            Array enumValues = Enum.GetValues(enumType);
            foreach (Enum enumValue in enumValues)
            {
                dic.Add(enumValue.ToString(), GetDisplayString(enumValue));
            }
            return dic;
        }
        /// <summary>
        /// 获取枚举的显示名称。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetDisplayString(this Enum value)
        {
            DisplayAttribute attribute = value.GetType().GetTypeInfo().GetField(value.ToString()).GetCustomAttributes(typeof(DisplayAttribute), false).FirstOrDefault() as DisplayAttribute;

            if (attribute != null)
            {
                return attribute.Name.IndexOf('|') != -1 ? attribute.Name.Split('|')[0] : attribute.Name;
            }
            
            DisplayNameAttribute displayAttribute = value.GetType().GetTypeInfo().GetField(value.ToString()).GetCustomAttributes(typeof(DisplayNameAttribute), false).FirstOrDefault() as DisplayNameAttribute;
            if (displayAttribute != null)
            {
                return attribute.Description.IndexOf('|') != -1 ? attribute.Description.Split('|')[0] : attribute.Description;
            }
            return value.ToString();
        }

        /// <summary>
        /// 获取枚举的说明文字。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetDescriptionString(this Enum value)
        {
            DescriptionAttribute attribute = value.GetType().GetTypeInfo().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault() as DescriptionAttribute;

            if (attribute != null)
            {
                return attribute.Description.IndexOf('|') != -1 ? attribute.Description.Split('|')[1] : attribute.Description;
            }

            return value.ToString();
        }

        /// <summary>
        /// 枚举转换。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T AsEnum<T>(this object obj)
            where T : struct
        {
            try
            {
                return (T)obj;
            }
            catch
            {
                T result;

                if (Enum.TryParse(obj.ToString(), true, out result))
                {
                    return result;
                }
                else
                {
                    return default(T);
                }
            }
        }

        /// <summary>
        /// 枚举转换。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static T AsEnum<T>(this object obj, T defaultValue)
            where T : struct
        {
            if (obj == null)
            {
                return defaultValue;
            }

            try
            {
                return (T)obj;
            }
            catch
            {
                return (T)Enum.Parse(typeof(T), obj.ToString(), true);
            }
        }
    }
}
